
//#include "io430.h"
//#include  <msp430x54xA.h>
#include "Drivers\Drivers.h"
#include "ESS_CommonDefine.h"
#include "ESS_MainSystemConfigDefine.h"

////////////////////////////////////////
// Global Parameters
unsigned char G_SystemModeStatus;  //Show ESS System current mode

//  watchdog timer Parameters
#define WatchdogForceSystemResetTimes   10  // time based= 1sec = 1000ms
unsigned char G_WatchdogDelayCount;
 
void main(void){
  unsigned char Temp_SystemModeStatus;  //For Temp ESS System current mode
  long temp_long;

  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
//  WDTCTL = WDT_ADLY_1000;                    // WDT 1000ms, ACLK, interval timer
//  SFRIE1 |= WDTIE;                          // Enable WDT interrupt  
  G_WatchdogDelayCount = 0;
  ///////////////////////////////////////////
  // Initial Mos, because must be turn off mos right away
  ///////////////////////////////////////////
  InitMosControl();
  setMosCHG(DeviceOff);
  setMosDSG(DeviceOff);

  ///////////////////////////////////////////
  // Initial Devices
  ///////////////////////////////////////////
  InitialBlinkingLED();
  ///////////////////////////////////////////
  // System_Initial_Date
  ///////////////////////////////////////////
  setupRTC(_ESS_System_Initial_Date_Year_, _ESS_System_Initial_Date_Month_, _ESS_System_Initial_Date_Day_,
           _ESS_System_Initial_Date_Hour_24hSystem_, _ESS_System_Initial_Date_Minute_, 0);

  //_EINT();  
  
  G_SystemModeStatus  = StartUp;
  Temp_SystemModeStatus = StartUp;
  ///////////////////////////////////////////
  while(1){
    
    switch(G_SystemModeStatus){
      case UnKnowStatus:
      case StartUp:
        G_SystemModeStatus = StartUpAndInitial();
        break;
      case AssemblyMode:
        G_SystemModeStatus = AssemblyModeFunc();
        break;
      case AssemblyModeReady:
        G_SystemModeStatus = AssemblyModeReadyFunc();
        break;
      case NormalMode:
        //G_DailyCounter = 0;
        //setDailyCounterStart(&DailyFlagFunc);
        EEPROM_Normal_Mode_Entering_Count +=1;
        setLEDsOnOff(Green_LED, true);
        
        Temp_SystemModeStatus = NormalModeFunc();
        WatchdogStop();
        ADC_Sampling_By_TimerA(DeviceOff);
        setBalanceChannel(Disable_Balancing);
        setCHGOverCurrentCounting(DeviceOff);
        setDSGOverCurrentCounting(DeviceOff);
        setLEDsOnOff(ALL_LEDs, false);
        set_Blinking_Function(ALL_LEDs, false);
        setMosCHG(DeviceOff);
        setMosDSG(DeviceOff);
        
        
        Init_EEPROM();
        Write_Saving_Array_To_EEPROM();
        __delay_cycles(5000);
        temp_long = (EEPROM_Saving_Section_Data_Count+1);
        temp_long = temp_long * Two_Days_minutes;
        if(EEPROM_Normal_Mode_Counter_By_Minutes > temp_long){
          Write_Record_Data_To_EEPROM();
        }
        Init_USCI_B0_IIC();
        G_SystemModeStatus = Temp_SystemModeStatus; //for delay to show the next System Mode 
        break;
      case FailShutdownMode:
        EEPROM_Fail_Mode_Entering_Count +=1;
        G_SystemModeStatus = FailShutdownModeFunc();
        break;
      case ShutdownMode:
        G_SystemModeStatus = ManualShutdownModeFunc();
        break;
      case CalibrationMode:         
        break;
      default:
        break;
    }
    
  }//while(1){  
}

void WatchdogStop(){
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  SFRIE1 &= ~WDTIE;                          // Enable WDT interrupt  
}
void ReStartWatchdogCount(){
  WDTCTL = WDT_ADLY_1000;                    // WDT 1000ms, ACLK, interval timer
  G_WatchdogDelayCount = 0;
  SFRIE1 |= WDTIE;                          // Enable WDT interrupt  
}










unsigned int value,click_count;
unsigned char readDataTemp[4];
unsigned char writeDataTemp[4];
unsigned long total_count;
unsigned long comm_fail_count, data_fail_count;
int main_( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  ///////////////////////////////////////////
  // Initial Devices
  ///////////////////////////////////////////
  InitialBlinkingLED();
  
  InitialDriversGlobleVariables();
  InitMultiplexer();
  InitLEDDisplay();
  InitTimerA();
  InitTimerB();
  InitButton();
  InitBalanceControl();
  
  //InitBalanceControlByPWM();
  InitAddressGetting();
  
  InitAdcReader();
  InitMosControl();
  Init_USCI_B0_IIC();
  Init_USCI_B1_IIC();
  Init_USCI_B2_IIC();
  __delay_cycles(1000); //1000 = 1ms

  _EINT();
  click_count = 0;
  value = 0;
  
  total_count = 0;
  data_fail_count = 0;
  comm_fail_count = 0;
  setMuxChannel(mux_ch3);
  Init_EEPROM();
      
  unsigned int loop_i;
  for(loop_i = 0; loop_i < EEPROM_Saving_Config_Data_Bytes; loop_i++){
    EEPROM_Saving_Config_Array[loop_i] = value++;
  }
  for(loop_i = 0; loop_i < Section_Of_Pack_Saving_Data_Bytes; loop_i++){
    EEPROM_Saving_Data_Array[loop_i] = value++;
  }
    
  value  = 0;
  value = Write_Key_To_EEPROM(0x3333);
  __delay_cycles(100);
  Init_USCI_B0_IIC();
  
//value = EEPROM_Saving_Section_Initial_Data      ;
//value = EEPROM_Saving_Section_Data_Count        ;
//total_count = EEPROM_Normal_Mode_Counter_By_Minutes   ;
//value = EEPROM_Normal_Mode_Entering_Count       ;
//value = EEPROM_Fail_Mode_Entering_Count         ;
//value = EEPROM_COC_Count                        ;
//value = EEPROM_DOC_Count                        ;
//value = EEPROM_CHG_Current_Range_Count          ;
//value = EEPROM_DSG_Current_Range_Count          ;
//value = EEPROM_OV_Count                         ;
//value = EEPROM_UV_Count                         ;
//value = EEPROM_OT_Count                         ;
//value = EEPROM_UT_Count                         ;
//value = Maximun_Pack_Voltage_To_EEPROM          ;
//value = Minimun_Pack_Voltage_To_EEPROM          ;
//value = Maximun_Pack_Current_To_EEPROM          ;
//value = Minimun_Pack_Current_To_EEPROM          ;
//value = Maximun_Pack_Temperature_To_EEPROM      ;
//value = Minimun_Pack_Temperature_To_EEPROM      ;  
  while(1){
      //P1OUT |= BIT5;
//    value = check_EEPROM_Data_Be_Initial();
//    value = InitStroeMemoryAndGetSettingData();
//    value = check_EEPROM_Data_Be_Initial();
//    clear_Saving_Array();
//    value = InitStroeMemoryAndGetSettingData();

//      writeDataTemp[0] = 0x46;  //cmd : _FETControl_
//      writeDataTemp[1] = 0x00;  //turn off CHG/DSG mos
//      writeDataTemp[2] = 0x00;
//      value = MasterIIC_Write_Bytes_UCB2(writeDataTemp, 3, true);
//      __delay_cycles(1000); //1000 = 1ms
//      writeDataTemp[1] = 0x06;  //turn on CHG/DSG mos
//      value = MasterIIC_Write_Bytes_UCB2(writeDataTemp, 3, true);
//      __delay_cycles(1000); //1000 = 1ms
//
    if(G_Device_Action_Controls & BUTTON_CLICK){
      click_count++;
      G_Device_Action_Controls &= ~BUTTON_CLICK;
    }
    if(G_Device_Action_Controls & BUTTON_LONG_PRESS){
      click_count = 0;
      G_Device_Action_Controls &= ~BUTTON_LONG_PRESS;
    }
    //P1OUT |= BIT5;
    __delay_cycles(1000); //1000 = 1ms
    //P1OUT &= ~BIT5;
  }
  return 0;
}


int main_test( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  ///////////////////////////////////////////
  // Initial Devices
  ///////////////////////////////////////////
  InitialBlinkingLED();
  
  InitialDriversGlobleVariables();
  InitMultiplexer();
  InitLEDDisplay();
  InitTimerA();
  InitTimerB();
  InitButton();
  InitBalanceControl();
  
  //InitBalanceControlByPWM();
  InitAddressGetting();
  
  InitAdcReader();
  InitMosControl();
  Init_USCI_B2_IIC();
  __delay_cycles(1000); //1000 = 1ms

  _EINT();
  click_count = 0;
  value = 0;
  
  total_count = 0;
  data_fail_count = 0;
  comm_fail_count = 0;
  setMuxChannel(mux_ch3);
      Init_EEPROM();
  while(1){
      //P1OUT |= BIT5;
    
      value = EEPROM_Read(0x7ffe, readDataTemp, 2);
      __delay_cycles(1000); //1000 = 1ms
      value = EEPROM_Read(0x7fff, readDataTemp, 2);
      __delay_cycles(1000); //1000 = 1ms
      writeDataTemp[0] = 0x31;
      writeDataTemp[1] = 0x55;
      writeDataTemp[2] = 0xaa;
      writeDataTemp[3] = 0x19;
      P1OUT |= BIT5;
      value = EEPROM_Write(0x7ffe, writeDataTemp, 2);
      P1OUT &= ~BIT5;
      //__delay_cycles(1000); //1000 = 1ms
      value = EEPROM_Read(0x7ffe, readDataTemp, 2);
      __delay_cycles(1000); //1000 = 1ms

      total_count++;
      //P1OUT |= BIT5;
      value = MasterIIC_WRead_Bytes_UCB2(0x1c, readDataTemp, 2, true);
      //__delay_cycles(1000); //1000 = 1ms
      value = MasterIIC_WRead_Bytes_UCB2(0x00, readDataTemp, 2, true);
      //__delay_cycles(1000); //1000 = 1ms
      
      writeDataTemp[0] = 0x00;  //cmd
      writeDataTemp[1] = 0x54;  //_OperationStatus_
      writeDataTemp[2] = 0x00;
      P1OUT |= BIT5;
      value = MasterIIC_Write_Bytes_UCB2(writeDataTemp, 3, true);
      P1OUT &= ~BIT5;
      if(value != I2cDone){
        if(value == I2cWriteFail){
          comm_fail_count++;
        }else{
          data_fail_count++;
        }
      }
         
      //__delay_cycles(1000); //1000 = 1ms
      value = MasterIIC_WRead_Bytes_UCB2(0x00, readDataTemp, 2, true);
      //__delay_cycles(1000); //1000 = 1ms
      writeDataTemp[0] = 0x00;  //cmd
      writeDataTemp[1] = 0x46;  //_FETControl_
      writeDataTemp[2] = 0x00;
      P1OUT |= BIT5;
      value = MasterIIC_Write_Bytes_UCB2(writeDataTemp, 3, true);
      P1OUT &= ~BIT5;
      if(value != I2cDone){
        if(value == I2cWriteFail){
          comm_fail_count++;
        }else{
          data_fail_count++;
        }
      }
      //__delay_cycles(1000); //1000 = 1ms
      value = MasterIIC_WRead_Bytes_UCB2(0x00, readDataTemp, 2, true);
      //__delay_cycles(1000); //1000 = 1ms

      P1OUT &= ~BIT6;
      P1OUT &= ~BIT5;
      P1OUT &= ~BIT7;
      if(value != I2cDone){
         //comm_fail_count++;
         //P1OUT |= BIT7;
      }else{
        //P1OUT &= ~BIT7;
      }
      if((readDataTemp[0] != 0x55) || (readDataTemp[1] != 0x72)){
        //data_fail_count++;
      }
      
      //P1OUT &= ~BIT5;
      if(total_count == 20000){
        //P1OUT |= BIT6;
        //break;
      }
    if(G_Device_Action_Controls & BUTTON_CLICK){
      
      
      click_count++;
      G_Device_Action_Controls &= ~BUTTON_CLICK;
    }
    if(G_Device_Action_Controls & BUTTON_LONG_PRESS){
      click_count = 0;
      G_Device_Action_Controls &= ~BUTTON_LONG_PRESS;
    }
    
    //P1OUT |= BIT5;
    __delay_cycles(1000); //1000 = 1ms
    //P1OUT &= ~BIT5;
    
    
  }
  
  
  return 0;
}

//      switch(temp){
//        case 0:
//          setLEDsOnOff(Green_LED, DeviceOn);
//          break;
//        case 1:
//          setLEDsOnOff(Green_LED, DeviceOff);
//          setLEDsOnOff(Red_LED, DeviceOn);
//          break;
//        case 2:
//          setLEDsOnOff(Red_LED, DeviceOff);
//          setLEDsOnOff(Yellow_LED, DeviceOn);
//          break;
//        case 3:
//          setLEDsOnOff(ALL_LEDs, DeviceOn);
//          break;
//        case 4:
//          set_Blinking_Function(Red_LED, DeviceOn);
//          break;
//        case 5:
//          set_Blinking_Function(Yellow_LED, DeviceOn);
//          break;
//        case 6:
//          set_Blinking_Function(ALL_LEDs, DeviceOn);
//          break;
//        case 7:
//          set_Blinking_Function(Red_LED, DeviceOff);
//          break;
//        case 8:
//          setLEDsOnOff(Red_LED, DeviceOn);
//          break;
//        case 9:
//          set_Blinking_Function(ALL_LEDs, DeviceOff);
//          break;
//        default:
//          break;
//      }
//      temp++;


// Watchdog Timer interrupt service routine
#pragma vector = WDT_VECTOR
__interrupt void WDT_ISR(void)
{
  __delay_cycles(1000); //1000 = 1ms
  if(G_WatchdogDelayCount >= WatchdogForceSystemResetTimes){
    //force system reset
    ////////////////////////////////////////////////////////////////////////////////////
    // C code to directly call an address location
    ((void (*)())0x350)();                  // Invalid fetch ("call #0350h")
    /* 0x350 is address of TA0R register and is within the module register memory
    address range (0x0100 --0x0FEF) */
    ////////////////////////////////////////////////////////////////////////////////////
    
  }else{
    G_WatchdogDelayCount++;
  }
}
